package org.hawk.gwt.ppc.scanner.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

final class ObjectTypeScope extends JavaTypeScope {
	static final ObjectTypeScope INSTANCE = new ObjectTypeScope();
	
	private List<JavaMethod> methods;
	
	private ObjectTypeScope() {
		super(null, 0, new LinkedList<JavaVariable>(), null);
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getVariables(int)
	 */
	@Override
	public List<JavaVariable> getVariables(int index) {
		return Collections.singletonList(
			new JavaVariable("class", "java.lang.Class", 0, this));
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getVariable(int, java.lang.String)
	 */
	@Override
	public JavaVariable getVariable(int index, String name) {
		if(!name.equals("class")){
			return null;
		}
		return getVariables(index).get(0);
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getMethods()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<JavaMethod> getMethods() {
		if(methods==null){
			methods = new ArrayList<JavaMethod>();
			methods.add(new JavaMethod("getClass", this, 0, 
				Collections.EMPTY_LIST,Class.class.getName()));
			methods.add(new JavaMethod("equals", this, 0, 
				Collections.singletonList(new JavaVariable(
					"arg0", Object.class.getName(), 0, null)),"boolean"));
			methods.add(new JavaMethod("toString", this, 0, 
				Collections.EMPTY_LIST,String.class.getName()));
			methods.add(new JavaMethod("hashCode", this, 0, 
				Collections.EMPTY_LIST,"int"));
			methods.add(new JavaMethod("clone", this, 0, 
				Collections.EMPTY_LIST,Object.class.getName()));
			methods.add(new JavaMethod("finalize", this, 0, 
				Collections.EMPTY_LIST,"void"));
			methods = Collections.unmodifiableList(methods);
		}
		return methods;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getMethod(java.lang.String, java.lang.String[])
	 */
	@Override
	public JavaMethod getMethod(String name, String... parametersTypes) {
		for(JavaMethod m : getMethods()){
			if(m.matches(name, parametersTypes)){
				return m;
			}
		}
		return null;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaScope#getParent()
	 */
	@Override
	public JavaScope getParent() {
		return null;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaScope#getScope(int)
	 */
	@Override
	public JavaScope getScope(int index) {
		return this;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaScope#getChildren()
	 */
	@Override
	public List<JavaScope> getChildren() {
		return Collections.emptyList();
	}
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return Object.class.toString();
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getImplementedInterfaces()
	 */
	@Override
	protected List<JavaTypeScope> getImplementedInterfaces() {
		return Collections.emptyList();
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getSuperClass()
	 */
	@Override
	protected JavaTypeScope getSuperClass() {
		return null;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#isAssignableFrom(org.hawk.gwt.ppc.scanner.utils.JavaTypeScope)
	 */
	@Override
	public boolean isAssignableFrom(JavaTypeScope type) {
		return true;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getClassName()
	 */
	@Override
	String getClassName() {
		return Object.class.getName();
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#getEntityType()
	 */
	@Override
	public String getEntityType() {
		return JavaClassDescriptor.CLASS_KEYWORD;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#isInterface()
	 */
	@Override
	public boolean isInterface() {
		return false;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#isClass()
	 */
	@Override
	public boolean isClass() {
		return true;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#isEnum()
	 */
	@Override
	public boolean isEnum() {
		return false;
	}
	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.scanner.utils.JavaTypeScope#isAnnotation()
	 */
	@Override
	public boolean isAnnotation() {
		return false;
	}
}
